#ifndef EVM_MODULE_CFFI_H
#define EVM_MODULE_CFFI_H

#ifdef __cplusplus
extern "C" {
#endif

#include "evm.h"

enum
{
    CFFI_OK,
    CFFI_FUNCTION_NOT_EXISTED,
    CFFI_ARG_TYPE_IS_NOT_BOOL,
    CFFI_ARG_TYPE_IS_NOT_INT,
    CFFI_ARG_TYPE_IS_NOT_FLOAT,
    CFFI_ARG_TYPE_IS_NOT_DOUBLE,
    CFFI_ARG_TYPE_IS_NOT_STRING,
    CFFI_ARG_TYPE_IS_NOT_CPOINTER,
    CFFI_ARG_TYPE_NOT_SUPPORT,
    CFFI_RETURN_TYPE_CPOINTER_IS_NULL,
    CFFI_RETURN_TYPE_EVM_TYPE_IS_NULL,
    CFFI_RETURN_TYPE_STRING_CREATE_FAILED,
    CFFI_RETURN_TYPE_BUFFER_CREATE_FAILED,
    CFFI_RETURN_TYPE_NOT_SUPPORT
};

typedef uint8_t CFFI_ERROR;


typedef struct _c_struct_signature {
  const char *name;
  int offset;
  char signature;
  const void *arg; /* Additional argument, used for some types. */
} c_struct_signature;

/**
 * @brief  evm_cffi_t 结构体定义
 * @note
 * @param  funcname   : 函数名称
 * @param  funcID     : 函数指针
 * @param  signature  : 描述函数的入口参数和出口参数
 */

typedef struct _evm_cffi_t {
    char *funcname;
    uintptr_t funcID;
    char *signature;
}evm_cffi_t;

/**
 * @brief  注册c标准函数和evm扩展函数到同一个模块
 * @note
 * @param  e:           虚拟机对象
 * @param  module_name: 模块名称
 * @param  cfuncs:      纯C函数
 * @param  efuncs:      evm扩展函数
 * @retval  返回evm的异常错误码
 */
evm_err_t evm_module_effi_create(evm_t *e, const char* module_name, evm_cffi_t *cfuncs, evm_builtin_t * efuncs);

/**
 * @brief  堆栈错误信息接口
 * @note
 * @param  e:           虚拟机对象
 * @param  module_name: 模块名称
 * @param  file_name:      文件名
 * @param  func_name:      函数名称
 * @param  signature:      函数签名
 * @param  error_code:     错误码
 * @param  error_code_index:    错误参数的索引
 * @param  error_arg:    错误参数值
 * @retval  返回evm的异常错误码
 */
evm_val_t evm_trace(evm_t *e, const char* module_name, const char* file_name, const char* func_name, const char* signature, CFFI_ERROR error_code, int error_code_index, evm_val_t error_arg);

/**
 * @brief  注册ffi模块
 * @note
 * @param  e:           虚拟机对象
 * @retval  返回evm的异常错误码
 */
evm_err_t evm_module_ffi(evm_t *e);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif

